﻿using System;
using System.Security.Cryptography;
using Entities;
using System.Text;
namespace Logic
{
    internal sealed class Password
    {
        private const byte MAX_LENGTH = 15;

        public static string Generate(dynamic i)
        {
            string rutid = Convert.ToString(i.rut);
            char[][] charGroups = new char[][] 
            {
            i.rut.ToCharArray(),
            i.name.ToCharArray(),
            i.middleName.ToCharArray(),
            i.lastName.ToCharArray(),
            i.secondLastName.ToCharArray(),
            i.email.ToCharArray(),
            i.cellPhone.ToCharArray(),
            i.telephone.ToCharArray()
                       };

            int[] charsLeftInGroup = new int[charGroups.Length];


            for (int j = 0; j < charsLeftInGroup.Length; j++)
            {
                charsLeftInGroup[j] = charGroups[j].Length;
            }

            int[] leftGroupsOrder = new int[charGroups.Length];

            for (int j = 0; j < leftGroupsOrder.Length; j++)
            {
                leftGroupsOrder[j] = j;
            }

            byte[] randomBytes = new byte[4];

            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            rng.GetBytes(randomBytes);

            int seed = (randomBytes[0] & 0x7f) << 24 |
                        randomBytes[1] << 16 |
                        randomBytes[2] << 8 |
                        randomBytes[3];

            Random random = new Random(seed);

            char[] password = null;

            password = new char[random.Next(MAX_LENGTH, MAX_LENGTH)];
            int nextCharIdx;
            int nextGroupIdx;
            int nextLeftGroupsOrderIdx;
            int lastCharIdx;
            int lastLeftGroupsOrderIdx = leftGroupsOrder.Length - 1;

            for (int j = 0; j < password.Length; j++)
            {

                if (lastLeftGroupsOrderIdx == 0)
                {
                    nextLeftGroupsOrderIdx = 0;
                }
                else
                {
                    nextLeftGroupsOrderIdx = random.Next(0, lastLeftGroupsOrderIdx);
                }

                nextGroupIdx = leftGroupsOrder[nextLeftGroupsOrderIdx];
                lastCharIdx = charsLeftInGroup[nextGroupIdx] - 1;

                if (lastCharIdx == 0)
                {
                    nextCharIdx = 0;
                }
                else
                {
                    nextCharIdx = random.Next(0, lastCharIdx + 1);
                }

                password[j] = charGroups[nextGroupIdx][nextCharIdx];

                if (lastCharIdx == 0)
                {
                    charsLeftInGroup[nextGroupIdx] = charGroups[nextGroupIdx].Length;
                }

                else
                {

                    if (lastCharIdx != nextCharIdx)
                    {
                        char temp = charGroups[nextGroupIdx][lastCharIdx];
                        charGroups[nextGroupIdx][lastCharIdx] = charGroups[nextGroupIdx][nextCharIdx];
                        charGroups[nextGroupIdx][nextCharIdx] = temp;
                    }

                    charsLeftInGroup[nextGroupIdx]--;
                }


                if (lastLeftGroupsOrderIdx == 0)
                {
                    lastLeftGroupsOrderIdx = leftGroupsOrder.Length - 1;
                }

                else
                {

                    if (lastLeftGroupsOrderIdx != nextLeftGroupsOrderIdx)
                    {
                        int temp = leftGroupsOrder[lastLeftGroupsOrderIdx];
                        leftGroupsOrder[lastLeftGroupsOrderIdx] =
                                    leftGroupsOrder[nextLeftGroupsOrderIdx];
                        leftGroupsOrder[nextLeftGroupsOrderIdx] = temp;
                    }

                    lastLeftGroupsOrderIdx--;
                }
            }


            return new string(password);
        }

        public static string GenerateIdPdf()
        {
            RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider();
            byte[] data = new byte[4];
            crypto.GetNonZeroBytes(data);
            StringBuilder response = new StringBuilder();
            foreach (byte b in data)
            {
                response.Append(b);
            }
            return response.ToString();
        }
    }
}